const fs = require('fs');
const zlib = require('zlib');
const path = require('path');
const { getDateFromFilename } = require('./path');
const { getExpiredDate } = require('./retention');
const isDevelopment = process.env.NODE_ENV === 'development';
const isDebug = process.env.LOG_DEBUG === 'true';

/**
 * 压缩日志文件
 * @param {string} filePath 日志文件路径
 * @returns {Promise<string>} 压缩后的文件路径
 */
function compressLogFile(filePath) {
  const gzPath = `${filePath}.gz`;
  const input = fs.createReadStream(filePath);
  const output = fs.createWriteStream(gzPath);
  const gzip = zlib.createGzip();

  return new Promise((resolve, reject) => {
    input
      .pipe(gzip)
      .pipe(output)
      .on('finish', () => {
        fs.unlinkSync(filePath); // 删除原始文件
        resolve(gzPath);
      })
      .on('error', (err) => {
        
        if (isDevelopment || isDebug) {
          console.error(`压缩日志文件失败: ${filePath}`, err);
        }
        reject(err);
      });
  });
}

/**
 * 压缩昨天的日志文件
 * @param {string} logDir 日志目录路径
 * @param {Object} levelPriority 日志级别优先级映射
 */
async function compressYesterdayLogs(logDir, levelPriority) {
  if (!fs.existsSync(logDir)) return;

  const yesterday = new Date();
  yesterday.setDate(yesterday.getDate() - 1);

  const year = String(yesterday.getFullYear());
  const month = String(yesterday.getMonth() + 1).padStart(2, '0');
  const day = String(yesterday.getDate()).padStart(2, '0');

  const validLevels = Object.keys(levelPriority);

  // 根据目录结构查找昨天的日志文件
  if (logDir.includes('logs2')) {
    // logs2目录结构: logs2/info/2025/01/2025-01-01_info.log
    for (const level of validLevels) {
      const levelDir = path.join(logDir, level, year, month);
      if (!fs.existsSync(levelDir)) continue;

      const files = fs.readdirSync(levelDir);
      for (const file of files) {
        if (file.startsWith(`${year}-${month}-${day}_`) && file.endsWith('.log')) {
          const filePath = path.join(levelDir, file);
          try {
            await compressLogFile(filePath);
          } catch (err) {
            
            if (isDevelopment || isDebug) {
              console.error(`压缩日志文件失败: ${filePath}`, err);
            }
          }
        }
      }
    }
  } else {
    // logs目录结构: logs/2025/01/01/2025-01-01_info.log
    const yearDir = path.join(logDir, year);
    if (!fs.existsSync(yearDir)) return;

    const monthDir = path.join(yearDir, month);
    if (!fs.existsSync(monthDir)) return;

    const dayDir = path.join(monthDir, day);
    if (!fs.existsSync(dayDir)) return;

    const files = fs.readdirSync(dayDir);
    for (const file of files) {
      if (file.endsWith('.log')) {
        const filePath = path.join(dayDir, file);
        try {
          await compressLogFile(filePath);
        } catch (err) {
          
          if (isDevelopment || isDebug) {
            console.error(`压缩日志文件失败: ${filePath}`, err);
          }
        }
      }
    }

    // 检查并删除空目录
    try {
      const remainingFiles = fs.readdirSync(dayDir);
      if (remainingFiles.length === 0) {
        fs.rmdirSync(dayDir);

        // 检查月份目录是否为空
        const monthFiles = fs.readdirSync(monthDir);
        if (monthFiles.length === 0) {
          fs.rmdirSync(monthDir);

          // 检查年份目录是否为空
          const yearFiles = fs.readdirSync(yearDir);
          if (yearFiles.length === 0) {
            fs.rmdirSync(yearDir);
          }
        }
      }
    } catch (err) {
      
      if (isDevelopment || isDebug) {
        console.error(`删除空目录失败:`, err);
      }
    }
  }
}

/**
 * 清理过期日志
 * @param {string} logDir 日志目录路径
 * @param {Object} retention 保留时间配置
 */
function cleanLogsByRetention(logDir, retention) {
  
  if (isDebug) {
    console.log(`[日志清理] 开始处理目录: ${logDir}`);
  }

  if (!fs.existsSync(logDir)) {
    if (isDebug) {
      console.log(`[日志清理] 目录不存在: ${logDir}`);
    }
    return;
  }

  const expiredDate = getExpiredDate(retention);

  if (isDebug) {
    console.log(`[日志清理] 过期时间: ${expiredDate.toISOString()}, 保留配置: ${retention.value}${retention.unit}`);
  }

  try {
    const logDirs = fs.readdirSync(logDir);

    if (isDebug) {
      console.log(`[日志清理] 在目录 ${logDir} 中找到 ${logDirs.length} 个项目`);
    }

    for (const item of logDirs) {
      const itemPath = path.join(logDir, item);
      let stat;

      try {
        stat = fs.statSync(itemPath);
      } catch (err) {
        
        if (isDebug) {
          console.log(`[日志清理] 无法获取文件状态 ${itemPath}: ${err.message}`);
        }
        continue;
      }

      if (stat.isDirectory()) {
        // 递归处理子目录
        cleanLogsByRetention(itemPath, retention);

        // 检查并删除空目录
        try {
          // 检查目录是否仍然存在（可能在递归过程中已被删除）
          if (fs.existsSync(itemPath)) {
            const files = fs.readdirSync(itemPath);
            if (files.length === 0) {
              if (isDebug) {
                console.log(`[日志清理] 删除空目录: ${itemPath}`);
              }
              fs.rmdirSync(itemPath);
            }
          }
        } catch (err) {
          
          if (isDebug) {
            console.log(`[日志清理] 无法处理目录 ${itemPath}: ${err.message}`);
          }
        }
      } else if (stat.isFile() && (item.endsWith('.log') || item.endsWith('.log.gz'))) {
        // 从文件名中提取日期
        const fileDate = getDateFromFilename(item);

        if (fileDate) {
          const isExpired = fileDate < expiredDate;
          if (isDebug) {
            console.log(`[日志清理] 检查日志文件: ${itemPath}, 文件名中的日期: ${fileDate.toISOString()}, 是否过期: ${isExpired}`);
          }

          if (isExpired) {
            try {
              if (isDebug) {
                console.log(`[日志清理] 删除过期日志文件: ${itemPath}`);
              }
              fs.unlinkSync(itemPath);
            } catch (err) {
              
              if (isDebug) {
                console.log(`[日志清理] 无法删除文件 ${itemPath}: ${err.message}`);
              }
            }
          }
        } else if (isDebug) {
          console.log(`[日志清理] 无法从文件名中提取日期: ${itemPath}`);
        }
      }
    }

    // 检查当前目录是否为空，如果为空则删除
    try {
      if (fs.existsSync(logDir)) {
        const files = fs.readdirSync(logDir);
        if (files.length === 0) {
          if (isDebug) {
            console.log(`[日志清理] 删除空目录: ${logDir}`);
          }
          fs.rmdirSync(logDir);
        }
      }
    } catch (err) {
      
      if (isDebug) {
        console.log(`[日志清理] 无法检查目录 ${logDir}: ${err.message}`);
      }
    }
  } catch (err) {
    
    if (isDevelopment || isDebug) {
      console.error(`[日志清理] 处理目录时发生错误:`, err);
    }
  }

  if (isDebug) {
    console.log(`[日志清理] 完成处理目录: ${logDir}`);
  }
}

module.exports = {
  compressLogFile,
  compressYesterdayLogs,
  cleanLogsByRetention
};